/*

    Copyright (C) 2011 University of Pittsburgh

    This file is part of Apollo.

    Apollo is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as
    published by the Free Software Foundation, either version 3 of
    the License, or (at your option) any later version.

    Apollo is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public
    License along with Apollo.  If not, see <http://www.gnu.org/licenses/>.

*/

/**
 *
 * @author Yang Hu <yah14@pitt.edu>
 */

var vaccAdminSchedule = new function(){
    //private functions
    function onGridInsertClicked(){
        //if user is still editing the table
        if (deliveryGrid.find('input').length != 0){
            alert('You must finish editing before you can add. To finish editing, click on the active cell (it is highlighted in yellow) and press the enter key.!');
            return;
        }
		
        if (currMode != 'rate'){
            alert('For rate model only!');
            return;
        }
		
        //get current select id
        var currid = deliveryGrid.getGridParam('selrow');
        if (currid == null){
            alert('You must select a row before you can insert.');
            return;
        }
		
        currid = parseInt(currid);
		
        //transfer current rate into an array
        var currentRawData = deliveryGrid.getRowData();
        //		logex2('currentRawData', currentRawData);
        //insert an new entry as its deep copy
        var newObject = jQuery.extend(true, {}, currentRawData[currid]);
        currentRawData.splice(currid, 0, newObject);
        //		logex2('currentRawData', currentRawData);
        //		logex2('currid', currid);
		
        //for every element after currid, increae the date for 1 day
        for (var idx = currid + 1; idx < currentRawData.length; idx++){
            var currrow = currentRawData[idx];
            var prerow = currentRawData[idx - 1];
			
            //			logex2('currrow', currrow);
            //			logex2('prerow', prerow);
			
            //increase only if the two date has no gap
            var nowDateStr = currrow.date;
            var nowDate = dateFromString(nowDateStr);

            var preDateStr = prerow.date;
            var preDate = dateFromString(preDateStr);
			
            var predictDate = dateToNextDays(nowDate, 1); 
			
            if (nowDate.getTime() == preDate.getTime()){
                currrow.day = parseInt( currrow.day ) + 1;
                currrow.date = dateToShortString(predictDate);
            }
            else{
                break;
            }
        }
		
        initRateGrid();
        loadRateAry(currentRawData);
		
        //focus to the new row
        //		logex2('currid', currid);
        deliveryGrid.editCell(currid + 2, 2, true);
		
    //update the chart
    //		var currentRawData = gridToRawArray();
    //		loadChart(currentRawData);
    };
    function onGridAddClicked(){
        //if user is still editing the table
        if (deliveryGrid.find('input').length != 0){
            alert('You must finish editing before you can add. To finish editing, click on the active cell (it is highlighted in yellow) and press the enter key.!');
            //	$(this).val(previousDate);
            return;
        }

        //get the lastrow
        var lastrowid = deliveryGrid.getDataIDs().max();
        var lastrow = deliveryGrid.getRowData(lastrowid);
		
        //generate a new row id
        var newRowId = lastrowid + 1;
		
        if (currMode == 'rate'){//update the delivery rate number
            var dateVal = lastrow.date;
            var lastDate = dateFromString(dateVal);
			
            var mylastrow = {
                day : parseInt(lastrow.day) + 1,
                date : dateToNextDaysStr(lastDate, 1),
                rate : parseInt (lastrow.rate)
            };
            deliveryGrid.addRowData(newRowId, mylastrow, 'last');
			
            var currentCount = parseInt( $('#vaccination-admin-delivery-rate-change').val() );
            currentCount++;
            $('#vaccination-admin-delivery-rate-change').val(currentCount);
        }else if (currMode == 'table'){
            var mylastrow = {
                delivery : parseInt(lastrow.delivery) + 1,
                day : parseInt(lastrow.day) + 1,
                quantity : parseInt(lastrow.quantity)
            };

            deliveryGrid.addRowData(newRowId, mylastrow, 'last');
			
            //update the deliveryCount
            var currentCount = parseInt( $('#vaccination-admin-delivery-number').val() );
            currentCount++;
            $('#vaccination-admin-delivery-number').val(currentCount);
        }
		
        //update the chart
        var currentRawData = gridToRawArray();
        loadChart(currentRawData);
    };
    function onGridDeleteClicked(){
        //if user is still editing the table
        if (deliveryGrid.find('input').length != 0){
            alert('You must finish editing before you can delete. To finish editing, click on the active cell (it is highlighted in yellow) and press the enter key.!');
            return;
        }
		
        if (currMode == 'rate'){//update the delivery rate number
            var currentCount = parseInt( $('#vaccination-admin-delivery-rate-change').val() );
            if (currentCount == 1)
                return;
			
            //get current selection id
            var rowid = deliveryGrid.getGridParam('selrow');
			
            if (rowid == null){
                alert('You must select a row before you can insert.');
                return;
            }
			
            deliveryGrid.delRowData( rowid );
			
            var currentCount = parseInt( $('#vaccination-admin-delivery-rate-change').val() );
            currentCount--;
            $('#vaccination-admin-delivery-rate-change').val(currentCount);
        }else if (currMode == 'table'){
            var ids = deliveryGrid.getDataIDs();
            if (ids.length == 0)
                return;
            //delete the last row @ buttom
            deliveryGrid.delRowData( ids.max() );
			
            //update the control
            var currentCount = parseInt( $('#vaccination-admin-delivery-number').val() );
            currentCount--;
            $('#vaccination-admin-delivery-number').val(currentCount);
        }
		
        //update the chart
        var currentRawData = gridToRawArray();
        loadChart(currentRawData);
    };
	
    function getVaccinationSchedule(){
        var mainGrid = $(dataExchange.gridId);
        var rowData = jqgridHelper.findDataByValue(mainGrid, 'pname', 'Vaccination Administration Schedule');

        if (rowData.length == 0)
            throw "Can't get Vaccination Administration Schedule";
		
        var rawData =  eval('(' + rowData[0].extra + ')');
		
        return rawData;
    }
	
    var chart;//global var for chart
    function initChart(rawData){		
        //chart
        chart = new Highcharts.Chart({
            chart: {
                renderTo: 'vaccination-admin-delivery-chart',
                defaultSeriesType: 'line',
                marginRight: 150,
                marginBottom: 60,
                height: 300,
                width: 475
            },
            title: {
                text: 'Delivery Schedule',
                x: -20 //center
            },
            subtitle: {
                text: 'Source: Apollo Webservice',
                x: -20
            },
            xAxis: {
                id : 'x-axis',
                title : {
                    margin: 10,
                    text: 'Days since first delivery'
                },
                labels: {
                    rotation: -90,
                    align: 'right',
                    style: {
                        font: 'normal 13px Verdana, sans-serif'
                    }
                }
            },
            yAxis: {
                title: {
                    text: '# doses delivered'
                },
                plotLines: [{
                    value: 0,
                    width: 1,
                    color: '#808080'
                }]
            },
            tooltip: {
                formatter: function() {
                    return '<b>'+ this.series.name +'</b><br/>'+
                    'Day ' + this.x +': '+ this.y;
                }
            },
            legend: {
                layout: 'vertical',
                align: 'right',
                verticalAlign: 'top',
                x: -10,
                y: 100,
                borderWidth: 0
            },
            series: [{
                id : 'non-cumulative',
                name : 'Non-Cumulative'
            }, {
                id : 'cumulative',
                name : 'Cumulative',
                visible : false
            }
            ]
        });
		
        loadChart(rawData);
    };
	
    function loadChart(rawData){
        //		console.log(JSON.stringify(rawData));
		
        //chart data
        var data = new Array();
        var xAxis = new Array();

        //get the max length
        var maxLength = rawData.length;
		
        var step = Math.floor(maxLength / 20);
        if (step < 1)
            step = 1;
		
        //for Non-Cumulative
        var ncumData = arrayHelper.resize(rawData, step);
        //console.log('nc: ' + JSON.stringify(ncumData));
		
        //for Cumulative
        var cumData = arrayHelper.resize(arrayHelper.cumulative(rawData), step);
        //console.log('c: ' + JSON.stringify(cumData));
		
        //xAxis lable
        var index = 0;
        while (xAxis.length * step < maxLength){
            xAxis.push(index * step);
            index = index + 1;
        }
		
        var ncs = chart.get('non-cumulative');
        var cs = chart.get('cumulative');
        var xa = chart.get('x-axis');
		
        ncs.setData(ncumData);
        cs.setData(cumData);
        xa.setCategories(xAxis);
    }
	
    function initRateGrid(){
        //set current mode
        currMode = 'rate';
		
        //unload grid first
        deliveryGrid = $("#vaccination-admin-delivery-table");
        deliveryGrid.GridUnload();
        //get the empty div by id
        deliveryGrid = $("#vaccination-admin-delivery-table");		
		
        //init in rate mode
        deliveryGrid.jqGrid({
            //			data: mydata,
            datatype: "local",
            //rowNum: mydata.length,
            loadonce:true,
            colNames:['Day', 'Date', 'Rate'],
            colModel:[
            {
                name:'day', 
                index:'day', 
                width:156, 
                editable: false, 
                editoptions:{
                    size:25
                }, 
                sorttype:"int"
            },

            {
                name:'date', 
                index:'date', 
                width:157, 
                editable: false,
                editoptions:{
                    size:25
                },
                sorttype:"date" , 
                editrules:{
                    date:true
                }, 
                datefmt: 'm-d-Y', 
                hidden:true
            },

            {
                name:'rate', 
                index:'rate', 
                width:256, 
                editable: false,
                editoptions:{
                    size:25
                }, 
                sorttype:"int", 
                editrules:{
                    number:true
                }
            }		
        ],
        width: 470,
        cellEdit: true,
        cellsubmit: 'clientArray',
        beforeSaveCell : function (	rowid, cellname, value, iRow, iCol){
            if (iCol != 1) //We just want to change the day when date changes
                return;
				
            var dateVal = $( "#vaccination-admin-date-of-first-delivery" ).val();
            var startDate = dateFromString(dateVal);
            var newDate = dateFromString(value);
				
            var diffDate = newDate - startDate;
				
            if (diffDate < 0){
                return dateVal; // make it to the begin date if the date is too small
            }else
                return value;
        },
        afterSaveCell : function(rowid, cellname, value, iRow, iCol){
            //				logex('after : ' + rowid + ' ' + cellname + ' ' + value + ' ' + iRow + ' ' + iCol);
				
            if (iCol == 1){ //We just want to change the day when date changes
                var dateVal = $( "#vaccination-admin-date-of-first-delivery" ).val();
                var startDate = dateFromString(dateVal);
                var newDate = dateFromString(value);
					
                var diffDate = newDate - startDate;
					
                //update the day value
                var rowData = deliveryGrid.getRowData(rowid);
                var numDays = diffDate / 86400000;
                rowData.day = Math.floor(numDays);
                deliveryGrid.setRowData(rowid, rowData);
            }
				
            //update the chart
            var currentRawData = gridToRawArray();
            loadChart(currentRawData);
        }
        });
};
	
function loadRateRawAry(rawData){
    loadRateAry(toRateAry(rawData));
}
	
function loadRateAry(mydata){
    //insert
    for(var i=0;i<=mydata.length;i++) 
        deliveryGrid.addRowData (i, mydata[i]);
		
    //set the rate control (number of delivery)
    $('#vaccination-admin-delivery-rate-change').val(mydata.length - 1);
		
    //hide the table control
    $('#vaccination-admin-delivery-number-div').hide();
    //show the rate control
    $('#vaccination-admin-delivery-rate-div').show();
}
	
function initTableGrid(rawData){
    //set current mode
    currMode = 'table';
		
    //unload grid first
    deliveryGrid = $("#vaccination-admin-delivery-table");
    deliveryGrid.GridUnload();
    //get the empty div by id
    deliveryGrid = $("#vaccination-admin-delivery-table");		
		
    //init in table mode
    deliveryGrid.jqGrid({
        //			data: mydata,
        datatype: "local",
        loadonce:true,
        rowNum: -1, 
        //			rowTotal: -1, 
        //			rowTotal: mydata.length, 
        //			rowList : [20,30,50], 
        //			scroll:1,
        colNames:['Delivery #', 'Day', 'Quantity'],
        colModel:[
        {
            name:'delivery', 
            index:'delivery', 
            width:156, 
            editable: false, 
            editoptions:{
                size:25
            }, 
            sorttype:"int"
        },

        {
            name:'day', 
            index:'day', 
            width:157, 
            editable: false, 
            editoptions:{
                size:25
            }, 
            sorttype:"int"
        },

        {
            name:'quantity', 
            index:'quantity', 
            width:256, 
            editable: false, 
            editoptions:{
                size:25
            }, 
            sorttype:"int"
        }		
        ],
        //			editurl:"edit.php",
        afterSaveCell : function(rowid, cellname, value, iRow, iCol){
            //update the raw data
				
            //update the chart
            var currentRawData = gridToRawArray();
            //				console.log(JSON.stringify(currentRawData));
            loadChart(currentRawData);
        },
        width: 470,
        cellEdit: true,
        cellsubmit: 'clientArray'
    });

    //construct data from parameter extra data
    var mydata = toTableAry(rawData);
		
    for(var i=0;i<=mydata.length;i++) 
        deliveryGrid.addRowData (i+1, mydata[i]);
		
    //set the rate control (number of delivery)
    $('#vaccination-admin-delivery-number').val(mydata.length);
		
    //show the table control
    $('#vaccination-admin-delivery-number-div').show();
    //hide the rate control
    $('#vaccination-admin-delivery-rate-div').hide();
};
	
function initControl(){
    var beginDatePicker = $( "#vaccination-admin-date-of-first-delivery" )
    beginDatePicker.datepicker();
    beginDatePicker.datepicker( "option", "dateFormat", "mm-dd-yy" );
		
    var previousDate = beginDatePicker.val();
		
    //reinit the rate table when first date changed
    beginDatePicker.change(function(){
        //if current model is table
        if (currMode == 'table')
            return;
			
        //if user is still editing the table
        if (deliveryGrid.find('input').length != 0){
            alert('You must finish editing before you can create a date. To finish editing, click on the active cell (it is highlighted in yellow) and press the enter key.!');
            $(this).val(previousDate);
            return;
        }
			
        previousDate = $(this).val();
			
        onRateMode();
    });
		
    //		$('#vaccination-admin-delivery-table-add').button().click(onGridAddClicked);
    //		$('#vaccination-admin-delivery-table-insert').button().click(onGridInsertClicked);
    //		$('#vaccination-admin-delivery-table-delete').button().click(onGridDeleteClicked);
    $('#vaccination-admin-delivery-table-add').button().click();
    $('#vaccination-admin-delivery-table-insert').button().click();
    $('#vaccination-admin-delivery-table-delete').button().click();
    $('#vaccination-admin-delivery-table-add').button().hide();
    $('#vaccination-admin-delivery-table-insert').button().hide();
    $('#vaccination-admin-delivery-table-delete').button().hide();
		
    $('#vaccination-admin-schedule-submit').button().click(function (){
        //if user is still editing the table
//        if (deliveryGrid.find('input').length != 0){
//            alert('You must finish editing before you can save. To finish editing, click on the active cell (it is highlighted in yellow) and press the enter key.');
//            //	$(this).val(previousDate);
//            return;
//        }
//			
//        var mainGrid = $(dataExchange.gridId);
//        var rowData = jqgridHelper.findDataByValue(mainGrid, 'pname', 'Vaccination Administration Schedule');
//        if (rowData == null || rowData.length < 1)
//            throw "Can't find Vaccination Administration Schedule Parameter!";
//			
//        rowData = rowData[0];
//			
//        var tgtRowId = rowData.id;
//        var currentRawData = gridToRawArray();
//        rowData['extra'] = JSON.stringify(currentRawData);
//			
//        //			console.log('currentRawData: ' + JSON.stringify(currentRawData) );
//        //			console.log('rowData: ' + JSON.stringify(rowData) );
//			
//        mainGrid.setRowData(tgtRowId, rowData);
			
    //
    //			console.log('after: ' + JSON.stringify( mainGrid.getRowData(tgtRowId)) );
    });
    $('#vaccination-admin-schedule-submit').button().hide();
		
    $('#vaccination-admin-rate-mode').click(onRateMode);
    $('#vaccination-admin-table-mode').click(onTableMode);
};
	
function toRateAry(srcAry){
    var dateVal = $( "#vaccination-admin-date-of-first-delivery" ).val();
    var startDate = dateFromString( dateVal );

    var rateAry = new Array();

    if (srcAry.length == 0)
        return rateAry;

    var day = 0, date = startDate;
    var lastQuantity = srcAry[0];

    //put in the first entry of the first day as the beginning
    rateAry.push({
        day : day,
        date : dateToNextDaysStr(date, day),
        rate : lastQuantity
    });

    for (var idx = 0; idx < srcAry.length; idx = idx + 1){
        var quantity = srcAry[idx];
        if (quantity != lastQuantity){
            rateAry.push({
                day : day,
                date : dateToNextDaysStr(date, day),
                rate : quantity
            });

            lastQuantity = quantity;
        }

        day = day + 1;
    }

    //put in the last entry to close it
    rateAry.push({
        day : srcAry.length,
        date : dateToNextDaysStr(date, srcAry.length + 1),
        rate : 0
    });
		
    //		console.log(srcAry.length);
    //		console.log(JSON.stringify(rateAry));

    return rateAry;
};
	
function toTableAry(srcAry){
    var tableAry = new Array();
		
    for (var idx = 0; idx < srcAry.length; ++idx){
        tableAry.push({
            delivery : idx,
            day : idx,
            quantity : srcAry[idx]
        });
    }
		
    return tableAry;
};
	
//when user select rate mode
function onRateMode(){
    //get current raw array data
    var rawAry = gridToRawArray();
		
    //init with rate mode with the raw array data
    initRateGrid();
    loadRateRawAry(rawAry);
		
    //enable the insert function
    $('#vaccination-admin-delivery-table-insert').button( "option", "disabled", false );
};
	
//when user select table mode
function onTableMode(){
    //get current raw array data
    var rawAry = gridToRawArray();
		
    //		logex2('rawAry.length', rawAry.length);
		
    //init with table mode with the raw array data
    initTableGrid(rawAry);
		
    //disable the insert function 
    $('#vaccination-admin-delivery-table-insert').button( "option", "disabled", true );
};
	
function gridToRawArray(){
    //get the raw array
    var rowData = deliveryGrid.getRowData();
    //		logex2('rowData', rowData);
    //		logex(JSON.stringify(rowData));
    var rawAry = new Array();
		
    //		console.log(currMode);
    //		console.log(JSON.stringify(rowData));
		
    if (currMode == 'rate'){
        //sort data by day, increasing order
        rowData.sort(function (left, right){
            return parseInt(left.day) >= parseInt(right.day);
        });
			
        //			console.log(rowData.length);
			
        for (var idx = 0; idx < rowData.length - 1; idx = idx + 1){
            var rateObj = rowData[idx];
				
            var beginDay = parseInt(rateObj.day);
            var endDay = parseInt(rowData[idx + 1].day);
				
            while(beginDay < endDay){
                rawAry[beginDay] = parseInt(rateObj.rate);
                beginDay = beginDay + 1;
            }
        }
			
    //			console.log('Rate: ' + rawAry.length);
    }else{
        for (var idx = 0; idx < rowData.length; idx = idx + 1){
            rawAry[idx] = parseInt(rowData[idx].quantity);
        }
			
    //append the end symbol at the end
    //			rawAry[idx] = 0;
    }
		
    //logex('rowData : ' + JSON.stringify(rowData));
    //logex('gridToRawArray : ' + JSON.stringify(rawAry));
		
    return rawAry;
};
//end private
	
//public functions
	
var deliveryGrid; //global var for deliveryGrid
var currMode; //global var for current mode
	
this.init = function() {
    try{
        //init common vars
        deliveryGrid = $("#vaccination-admin-delivery-table");
			
        initControl();
			
        var vacc = getVaccinationSchedule();
			
        //the init mode is rate grid
        //init with rate mode with the raw array data
        initRateGrid();
        loadRateRawAry(vacc);
			
        initChart(vacc);
			
        return $(this);
    }
    catch (err){
        alert(err.message);
    }
};
//end public

};

var vaccadmins = vaccAdminSchedule.init();